package com.innovation.ic.b1b.monitor.base.handler;

import com.innovation.ic.b1b.framework.util.StringUtils;
import com.innovation.ic.b1b.monitor.base.mapper.ServiceActiveJobLogMapper;
import com.innovation.ic.b1b.monitor.base.mapper.ServiceActiveJobMapper;
import com.innovation.ic.b1b.monitor.base.model.ServiceActiveJobLog;
import com.innovation.ic.b1b.monitor.base.pojo.constant.JobDataMapConstant;
import com.innovation.ic.b1b.monitor.base.pojo.constant.ServiceActiveJobLogConstant;
import com.innovation.ic.b1b.monitor.base.pojo.variable.serviceActiveJob.ServiceActiveJobData;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import javax.annotation.Resource;
import java.io.InputStream;
import java.sql.Date;
import java.util.Properties;

@Slf4j
public class ServiceActiveJobHandler extends QuartzJobBean {
    @Resource
    ServiceActiveJobMapper serviceActiveJobMapper;

    @Resource
    ServiceActiveJobLogMapper serviceActiveJobLogMapper;

    @Resource
    private HandlerHelper handlerHelper;

    @SneakyThrows
    @Override
    protected void executeInternal(org.quartz.JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("开始执行服务存活任务");
        JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap();
        int id = jobDataMap.getInt(JobDataMapConstant.ID);
        ServiceActiveJobData serviceActiveJobData = serviceActiveJobMapper.findId(id);
        if (serviceActiveJobData != null) {
            if (StringUtils.isEmpty(serviceActiveJobData.getProcessRegularExpression())) {//判断正在表达式不存在
                String message = "当前系统:" + serviceActiveJobData.getSystemName() + " 当前环境:" + serviceActiveJobData.getEnvironmentName() + " " + serviceActiveJobData.getServiceName() + "服务中正则表达式为空," + serviceActiveJobData.getServiceName() + "服务为没有存活";
                this.packageServiceActiveJobLog(serviceActiveJobData, ServiceActiveJobLogConstant.STATUS_ZERO, message);
                // 发送邮件
                handlerHelper.sendEmail(String.valueOf(serviceActiveJobData.getAlarmEmail()), message, null);
            } else {
                String data = this.order(ServiceActiveJobLogConstant.SSH_ORDER + ServiceActiveJobLogConstant.SSH_ORDER3 + serviceActiveJobData.getProcessRegularExpression() + ServiceActiveJobLogConstant.SSH_ORDER3 + ServiceActiveJobLogConstant.SSH_ORDER2,serviceActiveJobData.getUsername(),serviceActiveJobData.getPassword(),serviceActiveJobData.getIp(),serviceActiveJobData.getPort());
                if (!StringUtils.isEmpty(data)) {//服务返回 数据证明存活 有服务存在
                    this.packageServiceActiveJobLog(serviceActiveJobData, ServiceActiveJobLogConstant.STATUS_ONE, null);
                } else {
                    String message = "当前系统:" + serviceActiveJobData.getSystemName() + " 当前环境:" + serviceActiveJobData.getEnvironmentName() + " " + serviceActiveJobData.getServiceName() + "服务没有存活,当前正则表达式为:" + serviceActiveJobData.getProcessRegularExpression();
                    this.packageServiceActiveJobLog(serviceActiveJobData, ServiceActiveJobLogConstant.STATUS_ZERO, message);
                    // 发送邮件
                    handlerHelper.sendEmail(String.valueOf(serviceActiveJobData.getAlarmEmail()), message, null);
                }
            }
        } else {
            log.info("未在service_active_job表中查询到id=[{}]的配置信息,无法执行插入服务存活任务日志数据", id);
        }
    }

    //封装服务存活日志数据并添加
    private void packageServiceActiveJobLog(ServiceActiveJobData serviceActiveJobData, Integer active, String
            message) {
        // 服务存活任务日志表
        ServiceActiveJobLog serviceActiveJobLog = new ServiceActiveJobLog();
        serviceActiveJobLog.setServiceActiveJobId(serviceActiveJobData.getId());
        serviceActiveJobLog.setActive(active);
        serviceActiveJobLog.setStartTime(new Date(System.currentTimeMillis()));
        if (!StringUtils.isEmpty(message)) {
            serviceActiveJobLog.setDescription(message);
        }
        int insert = serviceActiveJobLogMapper.insert(serviceActiveJobLog);
        if (insert > 0) {
            log.info("服务存活任务日志表插入成功");
        }
    }

    /**
     * 通过当前命令直接返回信息
     *
     * @param command 服务器命令
     * @param username 账号
     * @param password 密码
     * @param ip IP
     * @param port 端口
     * @return
     * @throws SftpException
     */
    private String order(String command,String username,String password, String ip, String port) {
        int CONNECT_TIMEOUT = 30000;
        Session session = null;
        ChannelExec channel = null;
        InputStream inputStream = null;
        try {
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            //获取jsch的会话
            session = new JSch().getSession(username, ip, Integer.parseInt(port));
            session.setConfig(config);
            //设置密码
            session.setPassword(password);
            //连接  超时时间30s
            session.connect(CONNECT_TIMEOUT);
            //开启shell通道
            channel = (ChannelExec) session.openChannel("exec");
            inputStream = channel.getInputStream();
            channel.setCommand(command);
            // 获取执行脚本可能出现的错误日志
            channel.setErrStream(System.err);
            channel.connect();
            String result = IOUtils.toString(inputStream, "UTF-8");
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //断开连接后关闭会话
            session.disconnect();
            channel.disconnect();
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }
        return null;
    }
}
